package cn.sfrog.common.utils;

import org.apache.commons.lang3.time.DateFormatUtils;

import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalField;
import java.time.temporal.WeekFields;
import java.util.*;

/**
 * 时间工具类
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
    public static final String YYYY = "yyyy";

    public static final String YYYY_MM = "yyyy-MM";

    public static final String YYYY_MM_DD = "yyyy-MM-dd";

    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    public static final String DATE_FORMAT_Y_M_DHMS = "yyyy/MM/dd HH:mm:ss";

    public static final String DATE_FORMAT_Y_M_DHM = "yyyy/MM/dd HH:mm";

    public static final String DATE_FORMAT_YMDHM = "yyyy-MM-dd HH:mm";

    public static final String DATE_FORMAT_YMD = "yyyy-M-dd";

    public static final String DATE__FORMAT__YMD = "yyyy/MM/dd";
    public static final String DATE__FORMAT__YYMM = "yyyy-MM";

    public static final String DATE_FORMAT_年月 = "yyyy年MM月";
    public static final String DATE_FORMAT_年月日 = "yyyy年MM月dd日";
    public static final String DATE_FORMAT_DOT = "yyyy.MM.dd";
    public static final String DATE_FORMAT_年_月_日 = "yyyy年M月d日";

    public static final String DATE_FORMAT_HMS = "HH:mm:ss";

    public static final String DATE_FORMAT_YYYYMMDD = "yyyyMMdd";

    public static final String DATE_FORMAT_YYMMDD = "yyMMdd";

    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

    public static final int NUMBER_FOUR = 4;
    public static final int NUMBER_SIX = 6;
    public static final int NUMBER_EIGHT = 8;
    public static final int NUMBER_NINE = 9;
    public static final int NUMBER_SEVENTEEN = 17;
    public static final int NUMBER_FOUR_HUNDRED = 400;
    public static final int NUMBER_ONE_THOUSAND_AND_NINE_HUNDRED = 1900;
    public static final int NUMBER_NINE_NINE_NINE_NINE = 9999;

    /**
     * 获取当前Date型日期
     *
     * @return Date() 当前日期
     */
    public static Date getNowDate() {
        return new Date();
    }

    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd
     *
     * @return String
     */
    public static String getDate() {
        return dateTimeNow(YYYY_MM_DD);
    }

    public static final String getTime() {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }

    public static final String dateTimeNow() {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }

    public static final String dateTimeNow(final String format) {
        return parseDateToStr(format, new Date());
    }

    public static final String dateTime(final Date date) {
        return parseDateToStr(YYYY_MM_DD, date);
    }

    public static final String parseDateToStr(final String format, final Date date) {
        return new SimpleDateFormat(format).format(date);
    }

    public static final Date dateTime(final String format, final String ts) {
        try {
            return new SimpleDateFormat(format).parse(ts);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 日期路径 即年/月/日 如2018/08/08
     */
    public static final String datePath() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }

    /**
     * 日期路径 即年/月/日 如20180808
     */
    public static final String dateTime() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyyMMdd");
    }

    /**
     * 日期型字符串转化为日期 格式
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取服务器启动时间
     */
    public static Date getServerStartDate() {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }

    /**
     * 两个时间段是否有重叠时间
     */
    public static boolean overlapped(Date start1, Date end1, Date start2, Date end2) {
        if (start1.compareTo(start2) <= 0 && start2.compareTo(end1) <= 0 && end1.compareTo(end2) <= 0) {
            return true;
        } else if (start1.compareTo(start2) <= 0 && start2.compareTo(end2) <= 0 && end2.compareTo(end1) <= 0) {
            return true;
        } else if (start2.compareTo(start1) <= 0 && start1.compareTo(end2) <= 0 && end2.compareTo(end1) <= 0) {
            return true;
        } else if (start2.compareTo(start1) <= 0 && start1.compareTo(end1) <= 0 && end1.compareTo(end2) <= 0) {

            return true;
        } else {
            return false;
        }
    }

    /**
     * 计算两个时间差
     */
    public static String getDatePoor(Date endDate, Date nowDate) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }

    public static String getLiveDayString(Long birthday) {
        String str = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = GregorianCalendar.getInstance();
        calendar.setTime(new Date());
        int theYear = calendar.get(Calendar.YEAR);
        int theMonth = calendar.get(Calendar.MONTH) + 1;
        int theDay = calendar.get(Calendar.DATE);
        Date date = new Date(birthday);
        calendar.setTime(date);

        int birthYear = calendar.get(Calendar.YEAR);
        int birthMonth = calendar.get(Calendar.MONTH) + 1;
        int birthDay = calendar.get(Calendar.DATE);

        int year = theYear - birthYear;
        int month = theMonth - birthMonth;
        int day = theDay - birthDay;
        if (day < 0) {
            month--;
            day = day + 30;
        }
        if (month < 0) {
            year--;
            month = month + 12;
        }

        String retstr = "";
        if (year != 0) {
            retstr += (year + "岁");
        }
        if (month != 0) {
            retstr += (month + "个月");
        }
        if (day != 0) {
            retstr += (day + "天");
        }
        return retstr;
    }

    /**
     * 返回时间字符串列表 如["18:00","19:00"]
     */
    public static List<String> timeStrList() {
        Date now = new Date();
        int hour = getHour(now);
        List<String> timeStrList = new LinkedList<>();
        if (hour < NUMBER_NINE) {
            hour = NUMBER_EIGHT;
            now = setHour(now, NUMBER_EIGHT);
        }
        for (int i = 1; i <= (NUMBER_SEVENTEEN - hour); i++) {
            String timeStr = formatToStr(addHour(now, i), "HH:00");
            timeStrList.add(timeStr);
        }
        return timeStrList;
    }

    /**
     * 返回日期字符串
     */
    public static List<String> dateStrList(Date now, List<String> timeList) {
        List<String> dateList = new LinkedList<>();
        String today = formatToStr(now, DATE_FORMAT_YMD);
        if (timeList.size() > 0) {
            dateList.add(today);
        }
        String tomorow = formatToStr(addDate(now, 1), DATE_FORMAT_YMD);
        dateList.add(tomorow);
        String afterTomorrow = formatToStr(addDate(now, 2), DATE_FORMAT_YMD);
        dateList.add(afterTomorrow);
        return dateList;
    }

    /**
     * 获取上个月的时间
     */
    public static Date getLastMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MONTH, -1);
        return c.getTime();
    }


    /**
     * 是否在今天之前
     *
     * @param time
     * @return
     */
    public static boolean isBeforeToday(Long time) {
        if (time == null) {
            return true;
        }
        Calendar current = Calendar.getInstance();
        Calendar today = Calendar.getInstance();
        //  Calendar.HOUR——12小时制的小时数 Calendar.HOUR_OF_DAY——24小时制的小时数
        today.set(Calendar.HOUR_OF_DAY, 0);
        today.set(Calendar.MINUTE, 0);
        today.set(Calendar.SECOND, 0);
        today.set(Calendar.MILLISECOND, 001);
        current.setTimeInMillis(time);
        return current.before(today);
    }

    /**
     * 时间戳转化Date
     * @param str
     * @return
     */
    public static  Date timestampToDate(String str){
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        LocalDateTime ldt = LocalDateTime.parse(str,dtf);
        DateTimeFormatter fa = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String datetime2 = ldt.format(fa);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = format.parse(datetime2);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }


    /**
     * <pre>
     * 日期对象转字符串
     * </pre>
     *
     * @param date
     * @param format
     * @return
     */
    public static String formatToStr(Date date, String format) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(date);
    }

    /**
     * <pre>
     * 字符串转日期对象
     * </pre>
     *
     * @param dateStr
     * @param format
     * @return
     */
    public static Date formatToDate(String dateStr, String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(dateStr, pos);
        return strtodate;
    }

    /**
     * <pre>
     * 格式化日期字符串
     * </pre>
     *
     * @param dateStr
     * @param oldformat
     * @param newformat
     * @return
     */
    public static String formatStrToStr(String dateStr, String oldformat, String newformat) {
        return formatToStr(formatToDate(dateStr, oldformat), newformat);
    }

    /**
     * <pre>
     * 格式化日期（简短型）
     * </pre>
     *
     * @param date
     * @return 返回格式 yyyy-MM-dd
     */
    public static String formatShortStr(Date date) {
        if (date == null) {
            return null;
        }
        return formatToStr(date, YYYY_MM_DD);
    }

    /**
     * <pre>
     * 格式化日期（全格式型）
     * </pre>
     *
     * @param date
     * @return 返回格式 yyyy-MM-dd HH:mm:ss
     */
    public static String formatLongStr(Date date) {
        if (date == null) {
            return null;
        }
        return formatToStr(date, YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * <pre>
     *  格式化日期（时间型）
     * </pre>
     *
     * @param date
     * @return 返回格式 HH:mm:ss
     */
    public static String formatTimeStr(Date date) {
        if (date == null) {
            return null;
        }
        return formatToStr(date, DATE_FORMAT_HMS);
    }

    /**
     * <pre>
     * 增加天数
     * </pre>
     *
     * @param date 原始日期
     * @param days 增加的天数
     * @return 增加days天后的日期
     */
    public static Date addDate(Date date, int days) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, days);
        return c.getTime();
    }

    /**
     * <pre>
     * 增加月份
     * </pre>
     *
     * @param date   原始日期
     * @param months 增加的月数
     * @return 增加days天后的日期
     */
    public static Date addMonth(Date date, int months) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MONTH, months);
        return c.getTime();
    }

    /**
     * <pre>
     * 增加年份
     * </pre>
     *
     * @param date  原始日期
     * @param years 增加的年数
     * @return 增加days天后的日期
     */
    public static Date addYear(Date date, int years) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.YEAR, years);
        return c.getTime();
    }

    /**
     * 本周最后一天(周一开始)
     */
    public static Date getEndDayOfWeek() {
        LocalDate localDate = LocalDate.now();
        TemporalField fieldIso = WeekFields.of(DayOfWeek.MONDAY, 1).dayOfWeek();
        LocalDate localDateNew = LocalDate.from(localDate);
        localDateNew = localDateNew.with(fieldIso, 7);
        return Date.from(localDateNew.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 本周第一天(周一开始)
     */
    public static Date getStartDayOfWeek() {
        LocalDate localDate = LocalDate.now();
        TemporalField fieldIso = WeekFields.of(DayOfWeek.MONDAY, 1).dayOfWeek();
        LocalDate localDateNew = LocalDate.from(localDate);
        localDateNew = localDateNew.with(fieldIso, 1);
        return Date.from(localDateNew.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    /**
     * <pre>
     *  得到日期的小时(24小时制)
     * </pre>
     *
     * @param date
     * @return
     */
    public static int getHour(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * <pre>
     *  得到日期的分钟
     * </pre>
     *
     * @param date
     * @return
     */
    public static int getMinute(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.MINUTE);
    }

    /**
     * <pre>
     *  设置时间
     * </pre>
     *
     * @param date
     * @return
     */
    public static Date setHour(Date date, Integer hour) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, hour);
        return c.getTime();
    }

    /**
     * <pre>
     * 增加num秒后的时间
     * </pre>
     *
     * @param date
     * @return
     */
    public static Date addSecond(Date date, long num) {
        long time = date.getTime() + num * 1000;
        return new Date(time);
    }

    /**
     * <pre>
     * 增加num小时后的时间
     * </pre>
     *
     * @param date
     * @return
     */
    public static Date addHour(Date date, long num) {
        long time = date.getTime() + num * 3600 * 1000;
        return new Date(time);
    }

    /**
     * 判断是否润年
     *
     * @return
     */
    public static boolean isLeapYear(Date date) {
        /**
         * 详细设计： 1.被400整除是闰年，否则： 2.不能被4整除则不是闰年 3.能被4整除同时不能被100整除则是闰年 3.能被4整除同时能被100整除则不是闰年
         */
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int year = c.get(Calendar.YEAR);
        if ((year % NUMBER_FOUR_HUNDRED) == 0) {
            return true;
        } else if ((year % NUMBER_FOUR) == 0) {
            return (year % 100) != 0;
        } else {
            return false;
        }
    }

    /**
     * 获取年得第一天
     *
     * @param year
     * @return
     */
    public static Date getFristDateForYear(int year) {
        String timeStr = year + "-01-01 00:00:00";
        return formatToDate(timeStr, YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 获取年得最后一天
     */
    public static Date getLastDateForYear(int year) {
        String timeStr = year + "-12-31 23:59:59";
        return formatToDate(timeStr, YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 获取一个月的第一天
     *
     * @return
     */
    public static Date getFristDateForMonth(int year, int month) {
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, month - 1);
        c.set(Calendar.DAY_OF_MONTH, 1);
        c.set(Calendar.HOUR_OF_DAY, 00);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return c.getTime();
    }

    /**
     * 获取一个月的第一天
     *
     * @param date
     * @return
     */
    public static Date getFristDateForMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH, 1);
        return c.getTime();
    }

    /**
     * 获取一个月的第一天的开始时间
     *
     * @param date
     * @return
     */
    public static Date getFristTimeForMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH, 1);
        c.set(Calendar.HOUR_OF_DAY, 00);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return c.getTime();
    }

    /**
     * 获取一个月的最后一天
     *
     * @param date
     * @return
     */
    public static Date getEndDateOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int curMonth = c.get(Calendar.MONTH);
        c.set(Calendar.MONTH, curMonth + 1);
        c.set(Calendar.DAY_OF_MONTH, 0);
        return c.getTime();
    }

    /**
     * 获取一个月的最后一天
     *
     * @param date
     * @return
     */
    public static Date getEndTimeOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int curMonth = c.get(Calendar.MONTH);
        c.set(Calendar.MONTH, curMonth + 1);
        c.set(Calendar.DAY_OF_MONTH, 0);
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        c.set(Calendar.MILLISECOND, 999);
        return c.getTime();
    }

    public static Date getSomeDayOfMonth(Date date, Integer dayOfMonth) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
        return c.getTime();
    }

    /**
     * 判断二个时间是否在同一天
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean isSameDayDates(Date date1, Date date2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(date1);
        c2.setTime(date2);
        return c1.get(Calendar.DAY_OF_YEAR) == c2.get(Calendar.DAY_OF_YEAR);
    }

    /**
     * 判断二个时间是否在同一个周
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean isSameWeekDates(Date date1, Date date2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(date1);
        c2.setTime(date2);
        return c1.get(Calendar.WEEK_OF_YEAR) == c2.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 判断二个时间是否在同一个月
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean isSameMonthDates(Date date1, Date date2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(date1);
        c2.setTime(date2);
        return c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH);
    }

    /**
     * 判断二个时间是否在同一个年
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean isSameYearDates(Date date1, Date date2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(date1);
        c2.setTime(date2);
        return c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR);
    }

    /**
     * <pre>
     * 获取日期的年份
     * </pre>
     *
     * @param date
     * @return
     */
    public static int getYear(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.YEAR);
    }

    /**
     * <pre>
     * 获取日期的月份(特殊是月份要加1)
     * </pre>
     *
     * @param date
     * @return
     */
    public static int getMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.MONTH) + 1;
    }

    /**
     * <pre>
     * 获取日期的月份(特殊是月份要加1)
     * </pre>
     *
     * @param date
     * @return
     */
    public static int getDay(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * <pre>
     * 获取日期在一年中的第几周
     * </pre>
     *
     * @param date
     * @return
     */
    public static int getWeekForYear(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * <pre>
     * 获取日期在当前月中的第几周
     * </pre>
     *
     * @param date
     * @return
     */
    public static int getWeekForMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.WEEK_OF_MONTH);
    }

    /**
     * <pre>
     * 判断当前日期是周几
     * 1-7 分别表示周日,周一,周二,周三,周四,周五,周六
     * 1:SUNDAY, 2:MONDAY, 3:TUESDAY, 4:WEDNESDAY, 5:THURSDAY, 6:FRIDAY, 7:SATURDAY
     * </pre>
     *
     * @param date
     * @return
     */
    public static int getDayForWeek(Date date) {

        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.DAY_OF_WEEK);
    }

    /**
     * 获取本周周几
     * * 1-7 分别表示周日,周一,周二,周三,周四,周五,周六
     *
     * @return
     */
    public static Date getWeekDate(Integer weekDay) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_WEEK, weekDay);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        Date date = cal.getTime();
        return date;
    }


    /**
     * <pre>w
     * 获得一个日期所在周的周几的日期
     * 例：获得当前周的周一：getFristForWeek(new Date(),Calendar.MONDAY)
     * </pre>
     *
     * @param date    日期
     * @param weekday 周数 1-7 分别表示周日,周一,周二,周三,周四,周五,周六
     * @return 所在日期
     */
    public static Date getDayForWeek(Date date, int weekday) {
        Calendar c = Calendar.getInstance(Locale.CHINA);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, weekday);
        return c.getTime();
    }

    public static Date getMonDayForYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int between = cal.get(Calendar.DAY_OF_WEEK) - 1;
        int subMonday = 0;
        if (between >= 1 && between <= NUMBER_SIX) {
            subMonday = 1 - between;
        } else if (between == 0) {
            subMonday = -6;
        }
        cal.add(Calendar.DAY_OF_MONTH, subMonday);
        return cal.getTime();

    }

    public static Date getSunDayForYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int between = cal.get(Calendar.DAY_OF_WEEK) - 1;
        int subMonday = 0;
        if (between >= 1 && between <= NUMBER_SIX) {
            subMonday = 1 - between;
        } else if (between == 0) {
            subMonday = -6;
        }
        cal.add(Calendar.DAY_OF_MONTH, subMonday);
        cal.add(Calendar.DAY_OF_MONTH, 6);
        return cal.getTime();
    }

    /**
     * 两个时间之间的天数
     *
     * @return
     */
    public static int getDayNum(Date start, Date end) {
        return Integer.parseInt(String.valueOf((end.getTime() - start.getTime()) / (24 * 60 * 60 * 1000))) + 1;
    }

    /**
     * 两个时间之间的天数差
     *
     * @return
     */
    public static int getDayBetween(Date start, Date end) {
        return Integer.parseInt(String.valueOf((end.getTime() - start.getTime()) / (24 * 60 * 60 * 1000)));
    }

    /**
     * <pre>
     * 获取两个时间之间的日期数组
     * </pre>
     *
     * @param start
     * @param end
     * @return
     */
    public static List<Date> getDayArray(Date start, Date end) {
        List<Date> dates = new ArrayList<Date>();
        int count = getDayNum(start, end);
        for (int i = 0; i < count; i++) {
            Calendar c = Calendar.getInstance();
            c.setTime(start);
            c.add(Calendar.DAY_OF_YEAR, i);
            dates.add(c.getTime());
        }
        return dates;
    }

    /**
     * 获得昨天
     *
     * @return Date
     */
    public static Date getPreviousDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -1);
        return calendar.getTime();
    }

    /**
     * 获得明天
     *
     * @return Date
     */
    public static Date getNextDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, +1);
        return calendar.getTime();
    }


    /**
     * 获取某天的开始时间
     */
    public static Date getOtherDayStartDate(Integer daysNum) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, daysNum);
        calendar.set(Calendar.HOUR_OF_DAY, 00);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获得昨天结束时间
     *
     * @return Date
     */
    public static Date getPreviousEndDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    /**
     * 获得昨天结束时间
     *
     * @return Date
     */
    public static Date getPreviousEndDateInMin() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取某天的开始时间
     *
     * @return
     */
    public static Date getSomeDayStartTimes(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 00);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 000);
        return calendar.getTime();
    }

    /**
     * 获取某天的结束时间
     *
     * @return
     */
    public static Date getSomeDayEndTimes(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    /**
     * 获取某天的某个时间
     *
     * @return
     */
    public static Date getSomeDaySomeTimes(Date date, int day, int minute, int second) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, day);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);
        return calendar.getTime();
    }

    /**
     * 计算某年某周的开始日期
     *
     * @param yearNum 格式 yyyy ，必须大于1900年度 小于9999年
     * @param weekNum 1到52或者53
     * @return 日期
     */
    public static Date getYearWeekFirstDay(int yearNum, int weekNum) {
        if (yearNum < NUMBER_ONE_THOUSAND_AND_NINE_HUNDRED || yearNum > NUMBER_NINE_NINE_NINE_NINE) {
            throw new NullPointerException("年度必须大于等于1900年小于等于9999年");
        }

        Calendar c = new GregorianCalendar();
        c.set(Calendar.YEAR, yearNum);
        c.set(Calendar.WEEK_OF_YEAR, weekNum);
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
        return c.getTime();
    }

    /**
     * 计算某年某周的结束日期
     *
     * @param yearNum 格式 yyyy ，必须大于1900年度 小于9999年
     * @param weekNum 1到52或者53
     * @return 日期，格式为yyyy-MM-dd
     */
    public static Date getYearWeekEndDay(int yearNum, int weekNum) {
        if (yearNum < NUMBER_ONE_THOUSAND_AND_NINE_HUNDRED || yearNum > NUMBER_NINE_NINE_NINE_NINE) {
            throw new NullPointerException("年度必须大于等于1900年小于等于9999年");
        }

        Calendar c = new GregorianCalendar();
        c.set(Calendar.YEAR, yearNum);
        c.set(Calendar.WEEK_OF_YEAR, weekNum);
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
        c.roll(Calendar.DAY_OF_WEEK, 6);

        return c.getTime();
    }

    /**
     * 获取两个日期间的月份间隔
     *
     * @param start
     * @param end
     * @return
     */
    public static int getMonthInterval(Date start, Date end) {
        int monthInterval = 0;
        Calendar startCal = Calendar.getInstance();
        startCal.setTime(start);
        int sYear = startCal.get(Calendar.YEAR);
        int sMonth = startCal.get(Calendar.MONTH);
        int sDay = startCal.get(Calendar.DATE);

        Calendar endCal = Calendar.getInstance();
        endCal.setTime(end);
        int eYear = endCal.get(Calendar.YEAR);
        int eMonth = endCal.get(Calendar.MONTH);
        int eDay = endCal.get(Calendar.DATE);

        monthInterval = ((eYear - sYear) * 12 + (eMonth - sMonth));
        if (sDay < eDay) {
            monthInterval = monthInterval + 1;
        }
        monthInterval = Math.abs(monthInterval);
        return monthInterval;
    }

    /**
     * 获取两个日期间的年份间隔(同年算1年)
     *
     * @param start
     * @param end
     * @return
     */
    public static int getYearInterval(Date start, Date end) {
        int yearInterval = 0;
        Calendar startCal = Calendar.getInstance();
        startCal.setTime(start);
        int sYear = startCal.get(Calendar.YEAR);

        Calendar endCal = Calendar.getInstance();
        endCal.setTime(end);
        int eYear = endCal.get(Calendar.YEAR);
        yearInterval = eYear - sYear + 1;
        yearInterval = Math.abs(yearInterval);
        return yearInterval;
    }

    /**
     * <pre>
     *  上N个月的第一天
     * </pre>
     *
     * @param date
     * @param month
     * @return
     */
    public static Date getLastFristDateForMonth(Date date, int month) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.MONTH, c.get(Calendar.MONTH) - month);
        c.set(Calendar.DAY_OF_MONTH, 1);
        return c.getTime();
    }

    /**
     * <pre>
     *  获取下N个月的第一天
     * </pre>
     *
     * @param date
     * @param month
     * @return
     */
    public static Date getNextFristDateForMonth(Date date, int month) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.MONTH, c.get(Calendar.MONTH) + month);
        c.set(Calendar.DAY_OF_MONTH, 1);
        return c.getTime();
    }

    /**
     * 获取当前时间后一天(yyyy-MM-dd)
     *
     * @param
     * @return
     */
    public static String getNextDay() throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.DATE, +1);
        return format.format(c.getTime());
    }

    /**
     * 获取某天后一天(yyyy-MM-dd)
     *
     * @param date
     * @return
     */
    public static String getOneDayNextDay(String date) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(format.parse(date));
        c.add(Calendar.DATE, +1);
        return format.format(c.getTime());
    }

    /**
     * 获取当前时间七天前(yyyy-MM-dd)
     *
     * @param
     * @return
     */
    public static String getSevenDayBefore() throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        //过去七天
        c.setTime(new Date());
        c.add(Calendar.DATE, -6);
        return format.format(c.getTime());
    }


    public static void main(String[] args) {
        LocalDateTime localDateTime = LocalDateTime.now();
        ZoneId oldZone = ZoneId.of("Asia/Shanghai");
        LocalDateTime newDateTime = localDateTime.atZone(oldZone).withZoneSameInstant(ZoneId.of("-0600")).toLocalDateTime();
        System.out.println(newDateTime);
        try {
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
            Date start1 = sf.parse("2022-05-02");
            Date end1 = sf.parse("2022-05-03");
            Date start2 = sf.parse("2022-05-01");
            Date end2 = sf.parse("2022-05-04");
            System.out.println(overlapped(start1, end1, start2, end2));

        } catch (Exception e) {

        }

    }
}
